﻿
//
//
//

namespace Microsoft.OpenTurf.Silverlight.ViewModel
{
    using System;
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.Windows;
    using GalaSoft.MvvmLight.Messaging;
    using Microsoft.Maps.MapControl;
    using Microsoft.OpenTurf.Silverlight.Common;
    using Microsoft.OpenTurf.Silverlight.Shared;

    public class MapViewModel : MapControlBase
    {
        private string _baseUrl;

        public MapViewModel()
        {
            _baseUrl = ((App)App.Current).BaseUrl;
        }

        #region Methods
        protected override void Initialize()
        {
            MapFeeds = new ObservableCollection<IFeed>();
            MapFeeds.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(MapFeeds_Changed);

            Messenger.Default.Register<object>(this, NotificationTokens.GetMapDetails, e =>
            {
                ApplicationIdCredentialsProvider credProvider = App.Current.Resources["BingMapCredentials"] as ApplicationIdCredentialsProvider;

                string culture = MapControl.Culture;
                Credentials creds = new Credentials() { ApplicationId = credProvider.ApplicationId };
                LocationRect rect = MapControl.BoundingRectangle;

                MapDetails mapDetails = new MapDetails(creds, culture, rect);

                Messenger.Default.Send<MapDetails>(mapDetails, NotificationTokens.SendMapDetails);
            });

            Messenger.Default.Register<IFeed>(this, NotificationTokens.CreateOrShowLayer, e =>
            {
                if (e == null) return;
                if (MapFeeds.Contains(e))
                {
                    // Show Layer
                }
                else
                {
                    MapFeeds.Add(e);
                    RaisePropertyChanged("MapFeeds");
                }
            });

            Messenger.Default.Register<IFeed>(this, NotificationTokens.HideLayer, e =>
            {
                if (e == null) return;
                if (MapFeeds.Contains(e))
                {
                    // Hide Layer
                }
            });

            Messenger.Default.Register<Location>(this, (e) =>
            {
                MapControl.SetView(e, 14);
                RaisePropertyChanged("MapControl");
            });

            Messenger.Default.Register<MapMessage<MapPoint>>(this, MapMessages.MapCenterRequest, (e) =>
            {
                MapPoint point = new MapPoint(0, 0);

                if (CenterPoint != null)
                {
                    point.Latitude = CenterPoint.Latitude;
                    point.Longitude = CenterPoint.Longitude;
                }

                MapMessage<MapPoint> pointMessage = new MapMessage<MapPoint>(point);
                Messenger.Default.Send<MapMessage<MapPoint>>(pointMessage, MapMessages.MapCenterResponse);
            });

            Messenger.Default.Register<MapItemsControl>(this, e =>
            {
                MapControl.Children.Add(e);
                RaisePropertyChanged("MapControl");
            });
        }

        void KmlDocumentLoaded(FeedEventArgs e)
        {
            if (e.Feed == null) return;

            // ToDo: Check to see if it should create pins or regions
            var layer = BingMapHelper.CreateCustomPinLayer(e.Feed);

            if (layer.Children.Count > 0)
            {
                MapControl.Children.Add(layer);
                RaisePropertyChanged("MapControl");
            }
        }

        void MapFeeds_Changed(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    AddNewMapLayers(e.NewItems);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    RemoveMapLayers(e.OldItems);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    ChangeMapLayers(e.OldItems);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    // Don't anticipate a reset happening.
                    break;
                default:
                    break;
            }

        }

        private void ChangeMapLayers(IList iList)
        {
            throw new System.NotImplementedException();
        }
        private void RemoveMapLayers(IList iList)
        {
            throw new System.NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iList"></param>
        private void AddNewMapLayers(IList iList)
        {
            foreach (IFeed item in iList)
            {
                MapLayer layer;

                // HACK: Need to come up with a better way to resolve the Feeds
                // Support for more feeds in the future will not allow this method.
                try
                {
                    if (item.FeedItems != null)
                    {
                        layer = BingMapHelper.CreatePinLayer(item.FeedItems);
                        layer.Name = item.ID;
                        layer.Tag = item.Title;
                        MapControl.Children.Add(layer);
                    }
                    else
                    {
                        FeedProvider provider = new FeedProvider(_baseUrl, item);
                        provider.ProcessFeed += new FeedDownloadCompleteEventHandler(KmlDocumentLoaded);
                        provider.DownloadKMLFeedAsync(item.Link);
                    }
                }
                catch (Exception)
                { }
            }
            RaisePropertyChanged("MapControl");
        }
        #endregion

        #region Properties
        private Location _centerPoint;
        public Location CenterPoint
        {
            get { return _centerPoint; }
            set
            {
                _centerPoint = value;
                RaisePropertyChanged("CenterPoint");
            }
        }
        public ObservableCollection<IFeed> MapFeeds { get; private set; }
        public Map MapControl { get; set; }
        #endregion
    }
}